有限背包 - 單調隊列優化

我們先列出轉移式

dp(i,j)=max{dp(i1,j)dp(i1,jw)+vdp(i1,j2w)+vdp(i1,jkw)+kv

 

可以發現,對於 dp(i, j),他能轉移的點可能就是 j - 2w, j - w, j,對於 dp(i, j - w),他能轉移的點可能就是 j - 3w, j - 2w, j - w。

image-20231103165546670

所以對於 j % w 相同的狀態,其實可以用一個單調隊列來維護答案

image-20231103170205049

接下來要來看如何維護單調隊列裡面每項的 value。假若 dp(i, j) 從 dp(i - 1, j - kw) 轉移,轉移式就是 dp(i, j) = dp(i - 1, j - kw) + k * v,那我們要怎麼樣在單調對列裡面表示這個 k * w 的貢獻呢 ? 我們使用了一個類似前綴和的方法 假設我們將 j - kw 表示成 w',那麼轉移式就變成

dp(i, j)

其中我們就可以把 dp(i - 1, w') - (w' / w) * v 做為單調對列裡面的值,最後出來再統一加上 (j / w) * v 即可。注意到電腦是直接取下高斯,不過 j % w 與 j - kw % w 會是一樣的,所以不會有問題。